﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using S9Engine;
using System.Net.Mail;
using System.Text;
using System.Net;
using System.IO;


public partial class Order : Parser
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            InitAll();

            Session["CurrentPage"] = "Order.aspx";

            if (!CheckLogin()) Response.Redirect("login.aspx");
            _parser.SetCurrentDir("~/html");
            _parser.SetLanguageFile("~/templates/language.txt", _currentLanguage);

            string type = Request["type"] ?? "default";

            _DR.Refresh(System.Data.Objects.RefreshMode.StoreWins, _DR.Orders);

            switch (type)
            {
                case "default":
                    {
                        LoadFile("order.html", false);
                        LoadOrders();
                        break;
                    }
                case "view":
                    {
                        if (Request["id"] == null)
                        {
                            Response.Redirect("order.aspx");
                        }
                        else
                        {
                            LoadFile("order_add.html", false);
                            LoadOrdersByID(long.Parse(Request["id"]));
                        }
                        break;
                    }
                case "delete":
                    {
                        if (Request["id"] == null)
                        {
                            Response.Redirect("order.aspx");
                        }
                        else
                        {
                            DeleteOrdersByID(long.Parse(Request["id"]));
                            Response.Redirect("order.aspx");
                        }
                        break;
                    }
                case "confirm":
                    {
                        if (Request["email"] == null)
                        {
                            Response.Redirect("order.aspx");
                        }
                        else
                        {
                            ConfirmOrdersByEmail(Request["email"], long.Parse(Request["id"]));
                            Response.Redirect("order.aspx");
                        }
                        break;
                    }
                default: goto case "default";
            }
        }
        catch (Exception ex)
        {
            WriteError(ex);
        }
        finally
        {
            _parser.Parse("Main");
            _parser.Out("Main");
        }
    }

    private void LoadOrders()
    {
        try
        {
            List<Orders> orders = _DR.Orders.Where(m => m.LanguageCode.Equals(_currentLanguage)).OrderByDescending(o=>o.ID).ToList();
            
            string search = Request["search"] ?? string.Empty;

            if (!string.IsNullOrEmpty(search))
            {
                orders = orders.Where(o => o.Fullname.ToLower().Contains(search) ||
                    o.Phone.Contains(search) ||
                    o.Price.ToString().Equals(search) ||
                    o.Quantity.ToString().Equals(search)).ToList();

                _parser.Assign("searchValue", search);
            }

            double totalRecord = orders.Count();
            int page = int.Parse(Request["page"] ?? "1");
            int pageSize = _rowsPerPage;
            int totalPage = (int)(totalRecord / pageSize);

            if (totalPage * pageSize < totalRecord) totalPage++;
            List<Meta> metas = _DR.Meta.Where(m => m.Type.Equals("order")).ToList();
            if (totalRecord != 0)
            {
                int startRecord = (page == 1 ? 0 : ((page - 1) * pageSize));
                int endRecord = (int)(page * pageSize > totalRecord ? totalRecord : page * pageSize);

                for (int i = startRecord; i < endRecord; i++)
                {
                    _parser.Assign("orderID", orders[i].ID.ToString());
                    _parser.Assign("orderName", orders[i].Fullname);
                    _parser.Assign("orderEmail", orders[i].Email);
                    _parser.Assign("orderPhone", orders[i].Phone);
                    _parser.Assign("orderPrice", orders[i].Price.ToString("N0").Replace(',','.'));
                    _parser.Assign("orderQuantity", orders[i].Quantity.ToString());

                    string orderConfirm = "False";
                    Meta mt = metas.Where(m => m.Key.Equals("Order-Confirm") && m.Object.Equals(orders[i].ID)).FirstOrDefault();
                    if (mt != null) orderConfirm = mt.Value;

                    if (orderConfirm != "True") _parser.Parse("Main.Content.Table.TableItem.Confirm");

                    _parser.Parse("Main.Content.Table.TableItem");
                }

                _parser.Assign("totalPage", totalPage.ToString());
                _parser.Assign("totalRecord", totalRecord.ToString());
                _parser.Assign("currentPage", page.ToString());

                if (totalPage != 1)
                {
                    int pagingPage = page / _pageRange;
                    int startPage = 1;
                    int endPage = 1;

                    if (page % _pageRange == (_pageRange - 1) && page > _pageRange)
                    {
                        startPage = page;
                    }
                    else
                    {
                        startPage = (pagingPage * _pageRange == 0 ? 1 : pagingPage * _pageRange);
                    }

                    endPage = (startPage + (_pageRange - 1) > totalPage ? totalPage : startPage + (_pageRange - 1));

                    _parser.Assign("pageIndexPrevious", (page == 1 ? 1 : page - 1).ToString());
                    _parser.Assign("pageIndexNext", (page == totalPage ? totalPage : page + 1).ToString());


                    for (int i = startPage; i <= endPage; i++)
                    {
                        _parser.Assign("currentPageStyle", page == i ? " class=\"current\"" : string.Empty);

                        if (!string.IsNullOrEmpty(search)) _parser.Assign("searchInfo", string.Format("&search={0}", search));

                        _parser.Assign("pageIndex", i.ToString());
                        _parser.Parse("Main.Content.Table.Paging.PagingItem");
                    }

                    _parser.Parse("Main.Content.Table.Paging");
                    _parser.Parse("Main.Content.Table");
                }

                _parser.Parse("Main.Content.Table.Paging");
                _parser.Parse("Main.Content.Table");
            }

            _parser.Parse("Main.Content");

            orders = null;
        }
        catch (Exception ex)
        {
            WriteError(ex);
        }
    }

    private void LoadOrdersByID(long ID)
    {
        try
        {
            Orders order = _DR.Orders.Where(o => o.ID.Equals(ID) && o.LanguageCode.Equals(_currentLanguage)).FirstOrDefault();

            if (null == order) return;

            var orderMeta = _DR.Meta.Where(m => m.Type == "order" && m.Object == order.ID).ToList();

            string orderTime = orderMeta.Where(o => o.Key == "Time").Select(o => o.Value).FirstOrDefault() ?? string.Empty;
            string orderAddress = orderMeta.Where(o => o.Key == "Address").Select(o => o.Value).FirstOrDefault() ?? string.Empty;

            _parser.Assign("orderFullName", order.Fullname);
            _parser.Assign("orderEmail", order.Email);
            _parser.Assign("orderDate", orderTime);
            _parser.Assign("orderAddress", orderAddress);
            _parser.Assign("orderPhone", order.Phone);
            _parser.Assign("orderQuantity", order.Quantity.ToString());
            _parser.Assign("orderPrice", order.Price.ToString("N0").Replace(',','.'));

            var products = (from o in _DR.Orders.Where(o => o.LanguageCode == _currentLanguage && o.ID.Equals(order.ID))
                          //join m in _DR.Meta.Where(m => m.Type == "order" && m.Key == "OrderTime") on o.ID equals m.Object
                          join r in _DR.Relations.Where(r => r.Type == "order-product") on o.ID equals r.Parent
                          join p in _DR.Products on r.Child equals p.ID
                          join metaSale in _DR.Meta.Where(m=>m.Type.Equals("product") && m.Key.Equals("SalePrice")) on p.ID equals metaSale.Object into metaSaleFun
                          from mt in metaSaleFun.DefaultIfEmpty()
                          orderby p.Price descending, r.Order descending
                          select new
                          {
                              ID = p.ID,
                              Name = p.Name,
                              Price = p.Price,
                              SalePrice=mt.Value,
                              Description = p.Description,
                              Quantity = r.Order
                          }).ToList();

            foreach (var p in products)
            {
                double realPrice = (p.SalePrice != "" && p.SalePrice != "0") ? double.Parse(p.SalePrice) : p.Price;
                _parser.Assign("productID", p.ID.ToString());
                _parser.Assign("productName", p.Name);
                _parser.Assign("productPrice", realPrice.ToString("N0").Replace(',','.'));
                _parser.Assign("productDescription", p.Description);
                _parser.Assign("productQuantity", p.Quantity.ToString("N0").Replace(',','.'));
                _parser.Assign("productTotalPrice", (realPrice * p.Quantity).ToString("N0").Replace(',','.'));

                _parser.Parse("Main.Content.Table.TableItem");
            }

            if (products.Count > 0) _parser.Parse("Main.Content.Table");

            _parser.Parse("Main.Content");
        }
        catch (Exception ex)
        {
            WriteError(ex);
        }
    }

    private void DeleteOrdersByID(long ID)
    {
        try
        {
            Orders order = _DR.Orders.Where(o => o.ID.Equals(ID)).FirstOrDefault();

            if (order != null)
            {
                List<Meta> metas = _DR.Meta.Where(m => m.Type.Equals("order") && m.Object.Equals(ID)).ToList();

                foreach (Meta m in metas)
                {
                    _DR.DeleteObject(m);
                }

                _DR.DeleteObject(order);
                _DR.SaveChanges();

                metas = null;
            }

            order = null;
        }
        catch (Exception ex)
        {
            WriteError(ex);
        }
    }
    private void ConfirmOrdersByEmail(string email, long ID)
    {
        try
        {
            if (string.IsNullOrEmpty(email)) throw new Exception("Error: Invalid confirm email!");

            string fromEmail = _parser.GetConfig("ConfirmEmail", "gnat0309@gmail.com");

            string subject1 = _parser.GetConfig("ConfirmSubject", "Confirm") + " " + DateTime.Now.ToShortDateString();
            string name = _parser.GetConfig("NameEmail", "Bếp việt");

            string bodyfromtext = File.ReadAllText(Server.MapPath("uploads/mail/Confirm.txt"));
            string bodydecode = HttpUtility.HtmlDecode(bodyfromtext);
            //Send mail qua mail trung gian                    
            SendEmail("gnat0309@gmail.com", "145313211", "Bếp việt", email, "Bếp việt", subject1, DateTime.Now.ToShortDateString() + bodydecode);            
            Meta mt = _DR.Meta.Where(m => m.LanguageCode.Equals(_currentLanguage) && m.Object.Equals(ID) && m.Type.Equals("order") && m.Key.Equals("Order-Confirm")).FirstOrDefault();
            if (mt != null) { mt.Value = "True"; _DR.SaveChanges(); }
            else { AddNewMeta(ID, "order", "Order-Confirm", "True", true); }
        }
        catch (Exception ex) { WriteError(ex); }
    }

        
    private void SendEmail(string fromEmail, string fromPassword, string fromName, string toEmail, string toName, string subject, string body)
    {
        var fromAddress = new MailAddress(fromEmail, fromName);
        var toAddress = new MailAddress(toEmail, toName);

        var smtp = new SmtpClient
        {
            Host = "smtp.gmail.com",
            Port = 587,
            EnableSsl = true,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            UseDefaultCredentials = false,
            Credentials = new System.Net.NetworkCredential(fromAddress.Address, fromPassword)
        };

        using (var message = new MailMessage(fromAddress, toAddress)
        {
            BodyEncoding = System.Text.Encoding.UTF8,
            IsBodyHtml = true,
            SubjectEncoding = System.Text.Encoding.UTF8,
            Subject = subject,
            Body = body
        })
        {
            smtp.Send(message);
        };

        smtp = null;
    }    
}